package com.ruicar.afs.cloud.afscase.processor.query;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkProcessScheduleInfo;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoTempService;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseChannelInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseBaseInfoService;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseChannelInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.QueryRoleType;
import com.ruicar.afs.cloud.afscase.processor.enums.WorkflowType;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.query.QueryCondition;
import com.ruicar.afs.cloud.common.core.security.vo.RoleVo;
import com.ruicar.afs.cloud.common.core.security.vo.UserVo;
import com.ruicar.afs.cloud.common.core.util.SpringContextHolder;
import com.ruicar.afs.cloud.seats.entity.UserCollocation;
import com.ruicar.afs.cloud.seats.service.UserCollocationService;
import com.ruicar.afs.cloud.seats.util.PostStatus;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.CommonGetRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.GetAssignUserRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.request.UserOnlineRequest;
import com.ruicar.afs.cloud.workflow.api.dto.afsprocess.response.*;
import com.ruicar.afs.cloud.workflow.gwt.processor.AfsWorkFLowQueryProcessor;
import com.ruicar.afs.cloud.workflow.gwt.processor.DefaultAfsWorkFLowQueryProcessor;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description 信审常规流程查询操作处理
 * @Author Peng_Jinbo
 * @Date 2020/07/15 10:41
 */
@Component
@AllArgsConstructor
@Slf4j
public class NormalQueryProcessor implements AfsWorkFLowQueryProcessor {
    UserCollocationService userCollocationService;
    WorkProcessScheduleInfoService workProcessScheduleInfoService;
    WorkProcessScheduleInfoTempService workProcessScheduleInfoTempService;
    CaseChannelInfoService caseChannelInfoService;
    CaseBaseInfoService caseBaseInfoService;

    @Override
    public List<String> afsFLowKeys() {
        return Arrays.asList(new String[]{
                WorkflowType.NORMAL_NEW.getAfsFlowKey(),
                WorkflowType.NORMAL_OLD.getAfsFlowKey(),
                WorkflowType.NORMAL_APPOINT.getAfsFlowKey(),
                WorkflowType.CHANGE_ASSETS.getAfsFlowKey(),
                WorkflowType.RECONSIDER_APPLY.getAfsFlowKey(),
                WorkflowType.FORMAL_REVIEW.getAfsFlowKey()
        });
    }

    @Override
    public List<UserOnlineResponse> checkUserOnline(UserOnlineRequest userOnlineRequest) {
        log.info("在岗用户获取 ==> {}", userOnlineRequest);
        List<UserOnlineResponse> responses = new ArrayList<>();
        List<String> userNameList = userOnlineRequest.getUserInfos().stream().map(UserOnlineRequest.UserInfo::getUserName).collect(Collectors.toList());
        List<UserCollocation> userCollocationList = userCollocationService.list(
                Wrappers.<UserCollocation>lambdaQuery().in(UserCollocation::getLoginName, userNameList)
                        .eq(UserCollocation::getPostStatus, PostStatus.YES.getCode())
        );
        if (CollectionUtil.isNotEmpty(userCollocationList)) {
            for (UserCollocation userCollocation : userCollocationList) {
                UserOnlineResponse user = new UserOnlineResponse();
                user.setUserName(userCollocation.getLoginName());
                user.setOnLine(true);
                responses.add(user);
            }
        } else {
            log.warn("未存在在岗可分配人员");
        }
        log.info("在岗用户响应 ==> {}", responses);
        return responses;
    }

    @Override
    public GetAssignUserResponse getAssignUser(GetAssignUserRequest getAssignUserRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).getAssignUser(getAssignUserRequest);
    }

    @Override
    public QueryOrgConditionResponse queryOrgCondition(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).queryOrgCondition(commonGetRequest);
    }

    @Override
    public QueryRoleResponse queryRole(CommonGetRequest commonGetRequest) {
        log.info("设计器处理人类型获取 ==> {}", commonGetRequest);
        QueryRoleResponse roleResponse = new QueryRoleResponse();
        List<RoleVo> voList = new ArrayList<>();
        roleResponse.setRoleVos(voList);
        voList.add(getRoleVO(QueryRoleType.LEADER));
        voList.add(getRoleVO(QueryRoleType.DEALER));
        voList.add(getRoleVO(QueryRoleType.APPOINT_USER));
        log.info("设计器处理人类型响应 ==> {}", voList);
        return roleResponse;
    }

    @Override
    public Page<QueryUserResponse> queryUserInfo(QueryCondition<Map<String, Object>> queryCondition) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).queryUserInfo(queryCondition);
    }

    @Override
    public UserVo getRtnUserInfo(CommonGetRequest commonGetRequest) {
        log.info("回退人员获取 ==> {}", commonGetRequest);
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(commonGetRequest.getBizDataId());
        CaseChannelInfo channelInfo = caseChannelInfoService.getOne(
                Wrappers.<CaseChannelInfo>lambdaQuery().eq(CaseChannelInfo::getApplyNo, info.getApplyNo())
        );
        UserCollocation user = checkOnline(commonGetRequest.getBodyData());
        UserVo userVo = new UserVo();
        userVo.setUsername(Convert.toStr(channelInfo.getId(), "").equals(commonGetRequest.getBodyData())
                ? Convert.toStr(channelInfo.getId())
                : user.getLoginName());
        userVo.setUserRealName(Convert.toStr(channelInfo.getId(), "").equals(commonGetRequest.getBodyData())
                ? channelInfo.getDealerName()
                : user.getUserRealName());
        log.info("回退人员响应 ==> {},{}", userVo.getUsername(), userVo.getUserRealName());
        return userVo;
    }

    @Override
    public UserVo getApplyUserInfo(CommonGetRequest commonGetRequest) {
        log.info("经销商信息获取 ==> {}", commonGetRequest);
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(commonGetRequest.getBizDataId());
        CaseChannelInfo channelInfo = caseChannelInfoService.getOne(
                Wrappers.<CaseChannelInfo>lambdaQuery().eq(CaseChannelInfo::getApplyNo, info.getApplyNo())
        );
        UserVo userVo = new UserVo();
        userVo.setUsername(Convert.toStr(channelInfo.getId()));
        log.info("经销商信息响应 ==> {}", userVo.getUsername());
        return userVo;
    }

    @Override
    public UserVo getLeader(CommonGetRequest commonGetRequest) {
        log.info("组长信息获取 ==> {}", commonGetRequest);
        UserCollocation userCollocation = userCollocationService.getOne(
                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, commonGetRequest.getBodyData())
        );
        // 上一节点处理人登录名，没有配置坐席则直接返回上一岗位处理人
        String userName = Convert.toStr(commonGetRequest.getBodyData());
        if (Objects.nonNull(userCollocation)) {
            String leaderLoginName = userCollocation.getGroupLeaderLoginName();
            if (StrUtil.isNotBlank(leaderLoginName)) {
                UserCollocation leaderCollection = userCollocationService.getOne(
                        Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, leaderLoginName)
                );
                // 组长不在岗给组长代理人
                if (Objects.nonNull(leaderCollection)) {
                    // 组长在岗，任务分配给组长
                    if (PostStatus.YES.getCode().equals(leaderCollection.getPostStatus())) {
                        userName = leaderLoginName;
                    } else {
                        UserCollocation leaderAgentCollection = userCollocationService.getOne(
                                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, leaderCollection.getAgentLoginName())
                        );
                        // 组长代理人在岗，给组长代理人
                        if (Objects.nonNull(leaderAgentCollection) && PostStatus.YES.getCode().equals(leaderAgentCollection.getPostStatus())) {
                            userName = leaderAgentCollection.getLoginName();
                        } else {
                            // 组长代理人不在岗，给组长
                            userName = leaderLoginName;
                        }
                    }
                }
            }
        }
        UserVo userVo = new UserVo();
        userVo.setUsername(userName);
        log.info("组长信息响应 ==> {}", userName);
        return userVo;
    }


    @Override
    public UserVo getOperUser(CommonGetRequest commonGetRequest) {
        log.info("指定处理人获取 ==> {}", commonGetRequest);
        WorkProcessScheduleInfo info = workProcessScheduleInfoService.getById(commonGetRequest.getBizDataId());
        UserVo response = new UserVo();
        response.setUsername(info.getAppointHandler());
        log.info("指定处理人响应 ==> {}", response.getUsername());
        return response;
    }

    @Override
    public List<UserVo> commonNodeCheckUser(CommonGetRequest commonGetRequest) {
        return SpringContextHolder.getBean(DefaultAfsWorkFLowQueryProcessor.class).commonNodeCheckUser(commonGetRequest);
    }


    private RoleVo getRoleVO(QueryRoleType roleType) {
        RoleVo roleVo = new RoleVo();
        roleVo.setRoleCode(AfsEnumUtil.key(roleType));
        roleVo.setRoleName(AfsEnumUtil.desc(roleType));
        return roleVo;
    }

    /**
     * @Description 检查是否在岗, 不在岗给代理人
     * @Author Peng_Jinbo
     * @Date 2020/7/3 18:33
     */
    private UserCollocation checkOnline(String userName) {
        UserCollocation userCollocation = userCollocationService.getOne(
                Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, userName)
        );
        // 存在员工用户名
        if (Objects.nonNull(userCollocation)) {
            if (Objects.nonNull(userCollocation) && !PostStatus.YES.getCode().equals(userCollocation.getPostStatus())) {
                if (StrUtil.isNotBlank(userCollocation.getAgentLoginName())) {
                    UserCollocation agentCollocation = userCollocationService.getOne(
                            Wrappers.<UserCollocation>lambdaQuery().eq(UserCollocation::getLoginName, userCollocation.getAgentLoginName())
                    );
                    if (Objects.nonNull(agentCollocation) && PostStatus.YES.getCode().equals(agentCollocation.getPostStatus())) {
                        userCollocation = agentCollocation;
                    }
                }
            }
        }
        return userCollocation;
    }
}
